import SparkMD5 from 'spark-md5'

// 创建文件分片
export const createChunks = (file: File, CHUNK_SIZE: number) => {
	let start = 0
	const chunks: any[] = []
	while (start < file.size) {
		chunks.push(file.slice(start, start + CHUNK_SIZE))
		start += CHUNK_SIZE
	}
	return chunks
}

// 计算文件内容hash值
export const calculateHash = (file: File): Promise<string> => {
	return new Promise((resolve) => {
		const fileReader = new FileReader()
		fileReader.readAsArrayBuffer(file)
		fileReader.onload = function (e) {
			const spark = new SparkMD5.ArrayBuffer()
			spark.append((e.target as FileReader).result as ArrayBuffer)
			resolve(spark.end())
		}
	})
}

// 计算文件大小
export const getSize = (size: number) => {
	if (size < 1024) {
		return size.toFixed(0) + ' bytes'
	} else if (size < 1024 * 1024) {
		return (size / 1024.0).toFixed(0) + ' KB'
	} else if (size < 1024 * 1024 * 1024) {
		return (size / 1024.0 / 1024.0).toFixed(1) + ' MB'
	} else {
		return (size / 1024.0 / 1024.0 / 1024.0).toFixed(1) + ' GB'
	}
}

export const concurRequest = async (
	taskPool: Array<() => Promise<Response>>,
	max: number,
	onResult: (result: Response | unknown, index: number) => void
): Promise<void | Error> => {
	let concurrentCount = 0
	let index = 0
	let failed = false // 用来跟踪是否发生错误
	let finalResult: unknown | Error = undefined // 存储最终结果
	
	const request = async () => {
		if (failed || index === taskPool.length) {
			// 如果没有任务了或者已经失败了，检查是否所有任务都已完成
			if (index === taskPool.length && !failed) {
				finalResult = undefined // 或者可以设置一个表示成功的值
			}
			return
		}
		
		if (concurrentCount < max) {
			concurrentCount++
			const task = taskPool[index]
			index++
			
			try {
				const result = await task()
				onResult(result, index)
			} catch (err) {
				failed = true // 标记为失败
				finalResult = err // 存储错误作为最终结果
				onResult(err, index) // 传递错误
			} finally {
				concurrentCount--
				if (!failed) {
					await request() // 如果没有失败，继续下一个请求
				}
			}
		}
	}
	// 启动初始数量的请求
	for (let i = 0; i < Math.min(max, taskPool.length) && !failed; i++) {
		await request()
	}
	
	// 等待所有任务完成或失败
	while (concurrentCount > 0 && !failed) {
		await Promise.resolve().then(() => {
		})
	}
	
	// 如果有失败，返回错误；否则返回成功（或 void）
	if (failed) {
		return Promise.reject(finalResult)
	} else {
		return Promise.resolve()
	}
}
